<?php
/**
* 单例模式
* 1. 定义一个单例类 作为基类 会导致多个子类共享 同一个静态属性
* 2. 使用trait类 代替 基类 把 trait 的代码“内联”到类中 Trait 中的静态变量在每个使用它的类中是“独立”的。
* 3. 使用子类中都静态变量，并将基类的getInstance 中调用静态属性 都该为static::$instance
* 4. 自定义子类的静态变量，将类名作为键，实例作为值，这样就可以保证每个类都有自己独立的静态属性
**/
class Singleton 
{
    private static $instance;


    private function __construct(){}  #构造函数


    public static function getInstance(...$args)
    {
        if (!isset(self::$instance)) {
            self::$instance = new static(...$args); //类内部调用 实例化自己
        }
        return self::$instance;
    }
}

class Tian extends Singleton
{
}

class Di extends Singleton
{
}

$tian = Tian::getInstance();
$di = Di::getInstance();

$instance = Singleton::getInstance();

var_dump($tian, $di, $instance);



echo "\n------------\n";


trait TraitSingleton 
{
    private static $instance;


    private function __construct(){}  #构造函数


    public static function getInstance(...$args)
    {
        if (!isset(self::$instance)) {
            self::$instance = new static(...$args); //类内部调用 实例化自己
        }
        return self::$instance;
    }
}

class Tang
{
   use TraitSingleton;
}

class Song
{
    use TraitSingleton;
}

$tang = Tang::getInstance();
$song = Song::getInstance();

var_dump($tang, $song);


echo "\n----- 3 每个子类 都要定义 静态属性 否则就是共享父类的-------\n";

class Singleton1 
{
    protected static $instance;


    private function __construct(){}  #构造函数


    public static function getInstance(...$args)
    {
        if (!isset(static::$instance)) {
            static::$instance = new static(...$args); //类内部调用 实例化自己
        }
        return static::$instance;
    }
}

class Tian1 extends Singleton1
{
     protected static $instance;
}

class Di1 extends Singleton1
{
     protected static $instance;
}

$tian = Tian1::getInstance();
$di = Di1::getInstance();

$instance = Singleton1::getInstance();

var_dump($tian, $di, $instance);



echo "\n-----方法4 静态属性保存为数组 这样就可以用一个了-------\n";

class Singleton3 
{
    protected static $instance;


    private function __construct(){}  #构造函数


    public static function getInstance(...$args)
    {

        $class = get_called_class();
        if (!isset(self::$instance[$class])) {
            self::$instance[$class] = new static(...$args); //类内部调用 实例化自己
        }
        return self::$instance[$class];
    }
}

class Shang extends Singleton3
{
}

class Xia extends Singleton3
{
}

$tian = Shang::getInstance();
$di = Xia::getInstance();

$instance = Singleton3::getInstance();

var_dump($tian, $di, $instance);


echo "\n-----方法5 静态属性保存为数组 这样就可以用一个了-------\n";

class Singleton4 
{

    private function __construct(){}  #构造函数


    public static function getInstance(...$args)
    {

        static $instance;
        $class = get_called_class();
        if (!isset($instance[$class])) {
            $instance[$class] = new static(...$args); //类内部调用 实例化自己
        }
        return $instance[$class];
    }
}

class Ri extends Singleton3
{
}

class Yue extends Singleton3
{
}

$tian = Ri::getInstance();
$di = Yue::getInstance();

$instance = Singleton4::getInstance();

var_dump($tian, $di, $instance);